Passed
Branch master (f543ec)
by Andrew
05:45 queued 02:46
created

index.ts ➔ PluginCritical   C

Complexity

Conditions 10

Size

Total Lines 45
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 10.0862

Importance

Changes 0
Metric Value
eloc 37
dl 0
loc 45
ccs 19
cts 21
cp 0.9048
rs 5.9999
c 0
b 0
f 0
cc 10
crap 10.0862

How to fix   Complexity   

Complexity

Complex classes like index.ts ➔ PluginCritical often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import {Plugin} from 'rollup';
2 1
import path from 'path';
3 1
const critical = require('critical');
4
5 1
const criticalSuffix = '_critical.min.css';
6
7 1
const defaultCriticalConfig = {
8
  inline: false,
9
  minify: true,
10
  extract: false,
11
  width: 1200,
12
  height: 1200,
13
  concurrency: 4,
14
  penthouse: {
15
    blockJSRequests: false
16
  }
17
};
18
19
interface CriticalPages {
20
  uri: string;
21
  template: string;
22
}
23
24
interface CriticalPluginConfig {
25
  criticalUrl: string;
26
  criticalBase?: string;
27
  criticalPages: Partial<CriticalPages>[];
28
  criticalConfig?: Partial<CriticalConfig>;
29
}
30
31
function PluginCritical(pluginConfig: CriticalPluginConfig, callback?: Function): Plugin {
32 1
  return {
33
    name: 'critical',
34
    async writeBundle(outputOptions, bundle) {
35 1
      const css: Array<string> = [];
36
      // Find all of the generated CSS assets
37 2
      if (bundle) {
38 1
        for (const chunk of Object.values(bundle)) {
39 4
          if (chunk.type === 'asset' && chunk.fileName.endsWith('.css')) {
40 2
            if (outputOptions.dir !== undefined) {
41 1
              const cssFile = path.join(outputOptions.dir, chunk.fileName);
42 1
              css.push(cssFile);
43
            }
44
          }
45
        }
46
        // If we have no CSS, skip bundle
47 2
        if (!css.length) {
48
          return;
49
        }
50
      }
51
      // Iterate through the pages
52 1
      for (const page of pluginConfig.criticalPages) {
53 1
        const criticalBase = pluginConfig.criticalBase;
54 1
        const criticalSrc = pluginConfig.criticalUrl + page.uri;
55 1
        const criticalDest = page.template + criticalSuffix;
56
        // Merge in our options
57 1
        const options = Object.assign(
58
            { css },
59
            defaultCriticalConfig,
60
            {
61
              base: criticalBase,
62
              src: criticalSrc,
63
              target: criticalDest,
64
            },
65
            pluginConfig.criticalConfig
66
        );
67
        // Generate the Critical CSS
68 1
        console.log(`Generating critical CSS from ${criticalSrc} to ${criticalDest}`);
69 1
        await critical.generate(options, (err: string) => {
70 2
          if (err) {
71
            console.error(err);
72
          }
73 2
          if (callback) {
74 1
            callback(err);
75
          }
76
        });
77
      }
78
    }
79
  }
80
};
81
82
export default PluginCritical
83